package com.parking.status.sync.netty.client;

import com.parking.status.sync.netty.entity.ContentBase;
import com.parking.status.sync.netty.entity.RequestPre;
import com.parking.status.sync.netty.server.ChannelRepository;
import com.parking.status.sync.netty.server.ServerChannelInitializer;
import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * Created by Administrator on 2015/9/15.
 */
public class TcpClient {


    private Bootstrap clientBootstrap;

    @Autowired
    private ClientChannelInitializer clientChannelInitializer;

    private Channel clientChannel;

    private String tcpIp;

    private int tcpPort;

    private EventLoopGroup group;

    public TcpClient(String ip, int port) {
        this.tcpIp = ip;
        this.tcpPort = port;
    }

    public void start() throws Exception {

        if(clientChannel != null && clientChannel.isActive()) {
            return;
        }

//        clientChannelInitializer = new ClientChannelInitializer();
        group = new NioEventLoopGroup();
        try {
            clientBootstrap = new Bootstrap();
            //创建InetSocketAddress并设置到Bootstrap中，InetSocketAddress是指定连接的服务器地址
            clientBootstrap.group(group).channel(NioSocketChannel.class)
                    .option(ChannelOption.SO_KEEPALIVE, true)
                    .remoteAddress(tcpIpPort())
                    .handler(clientChannelInitializer);
            //调用Bootstrap.connect()来连接服务器
            ChannelFuture channelfuture = clientBootstrap.connect().sync();
            clientChannel = channelfuture.channel();

//            channelfuture.channel().closeFuture().sync();

        } finally {
//            //最后关闭EventLoopGroup来释放资源
//            group.shutdownGracefully().sync();
        }
    }

    public void stop() throws Exception {
        if(clientChannel != null) {
            clientChannel.closeFuture().sync();
            group.shutdownGracefully().sync();
        }
    }

    private InetSocketAddress tcpIpPort() {

        return new InetSocketAddress(tcpIp, tcpPort);
    }

//    @Bean(name = "channelRepository")
//    public ChannelRepository channelRepository() {
//
//        return new ChannelRepository();
//    }

//    public void send(String content) {
//        ChannelFuture lastWriteFuture = null;
//        lastWriteFuture = clientChannel.writeAndFlush(content + "\r\n");
//
//        try {
//            if (content.equalsIgnoreCase("end"))
//            {
//                clientChannel.closeFuture().sync();
//            }
//            if (lastWriteFuture != null)
//            {
//                lastWriteFuture.sync();
//            }
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
//    }

    public void send(ContentBase content) {
        if (content == null) {
            return;
        }

        ChannelFuture lastWriteFuture = null;
        lastWriteFuture = clientChannel.writeAndFlush(content);

        try {
            if (lastWriteFuture != null)
            {
                lastWriteFuture.sync();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void send(RequestPre request) {
        if(clientChannel == null || !clientChannel.isActive()) {
            return;
        }

        if (request == null) {
            return;
        }

        ChannelFuture lastWriteFuture = null;
        lastWriteFuture = clientChannel.writeAndFlush(request);

        try {
            if (lastWriteFuture != null)
            {
                lastWriteFuture.sync();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
